package com.alpha.core.http;

import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.http.HttpStatus;

/**
 * 响应统一格式
 *
 * @author chenruwan
 * @since 2022-01-01
 */
@Data
public class Response<T> {
    // 至少要提供 Getter 方法，否则请求会返回 HttpStatus.NOT_ACCEPTABLE

    @Schema(description = "响应码")
    private int status;

    @Schema(description = "提示信息")
    private String message;

    // 其他可携带信息: path/timestamp/error/requestId

    private T data;

    public Response() {
    }

    public Response(HttpStatus status) {
        this(status.value(), status.getReasonPhrase(), null);
    }

    public Response(HttpStatus status, T data) {
        this(status.value(), status.getReasonPhrase(), data);
    }

    public Response(int status, String message) {
        this(status, message, null);
    }

    public Response(int status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    @JsonIgnore
    public boolean isSuccess() {
        return this.status == HttpStatus.OK.value();
    }

    @JsonIgnore
    public boolean isFailure() {
        return !isSuccess();
    }

    public static <T> Response<T> success() {
        return success(null, HttpStatus.OK.getReasonPhrase());
    }

    public static <T> Response<T> message(String message) {
        return success(null, message);
    }

    public static <T> Response<T> success(T data) {
        return success(data, HttpStatus.OK.getReasonPhrase());
    }

    public static <T> Response<T> success(T data, String message) {
        return new Response<>(HttpStatus.OK.value(), message, data);
    }

    public static <T> Response<T> failure(HttpStatus status) {
        return failure(status.value(), status.getReasonPhrase(), null);
    }

    public static <T> Response<T> failure(HttpStatus status, String message) {
        return failure(status.value(), message, null);
    }

    public static <T> Response<T> failure(HttpStatus status, String message, T data) {
        return failure(status.value(), message, data);
    }

    public static <T> Response<T> failure(int status, String message) {
        return failure(status, message, null);
    }

    public static <T> Response<T> failure(int status, String message, T data) {
        return new Response<>(status, message, data);
    }
}
